package kubeutils

import (
	"context"
	"encoding/json"
	"fmt"
	"log/slog"
	"os/exec"
	"strings"
	"time"
)

// PodStatus represents the status of a Kubernetes pod
type PodStatus struct {
	Namespace string
	Name      string
	Status    string
	CreatedAt time.Time
}

// CleanupNonRunningPods cleans up pods that are not in Running, Terminating, or ContainerCreating state
func CleanupNonRunningPods() error {
	slog.Info("开始检查非Running状态的Pod")

	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()

	// 使用JSON格式输出，更可靠
	cmd := exec.CommandContext(ctx, "kubectl", "get", "po", "-A", "-o", "json")
	output, err := cmd.CombinedOutput()
	if err != nil {
		if ctx.Err() != nil {
			return fmt.Errorf("kubectl command timed out: %v", ctx.Err())
		}
		return fmt.Errorf("failed to execute kubectl command: %v, output: %s", err, string(output))
	}

	// 使用JSON解析，更可靠
	nonRunningPods, err := parseNonRunningPodsJSON(output)
	if err != nil {
		return fmt.Errorf("failed to parse kubectl output: %v", err)
	}

	// Display pods to be cleaned up
	displayNonRunningPods(nonRunningPods)

	// Clean up the pods with smart strategy
	if len(nonRunningPods) > 0 {
		if err := cleanupPodsWithStrategy(nonRunningPods); err != nil {
			return fmt.Errorf("failed to clean up pods: %v", err)
		}
	} else {
		fmt.Println("未发现需要清理的非Running状态Pod")
	}

	return nil
}

// 定义JSON结构
type PodList struct {
	Items []struct {
		Metadata struct {
			Namespace         string `json:"namespace"`
			Name              string `json:"name"`
			CreationTimestamp string `json:"creationTimestamp"`
		} `json:"metadata"`
		Status struct {
			Phase string `json:"phase"`
		} `json:"status"`
	} `json:"items"`
}

// 使用JSON解析kubectl输出
func parseNonRunningPodsJSON(output []byte) ([]PodStatus, error) {
	var podList PodList
	if err := json.Unmarshal(output, &podList); err != nil {
		return nil, fmt.Errorf("failed to unmarshal JSON: %v", err)
	}

	var nonRunningPods []PodStatus
	for _, item := range podList.Items {
		namespace := item.Metadata.Namespace
		name := item.Metadata.Name
		status := item.Status.Phase

		// 解析创建时间
		var createdAt time.Time
		if item.Metadata.CreationTimestamp != "" {
			createdAt, _ = time.Parse(time.RFC3339, item.Metadata.CreationTimestamp)
		}

		// 只过滤非Running和非ContainerCreating状态的Pod
		if status != "Running" && status != "ContainerCreating" {
			nonRunningPods = append(nonRunningPods, PodStatus{
				Namespace: namespace,
				Name:      name,
				Status:    status,
				CreatedAt: createdAt,
			})
		}
	}

	return nonRunningPods, nil
}

// displayNonRunningPods displays the list of non-running pods
func displayNonRunningPods(pods []PodStatus) {
	fmt.Println("\n【待清理的非Running状态Pod如下】:")
	if len(pods) == 0 {
		fmt.Println("未发现符合条件的Pod")
		return
	}

	// Display header
	fmt.Printf("%-20s %-40s %-15s %-20s\n", "命名空间", "Pod名称", "状态", "创建时间")
	fmt.Println(strings.Repeat("-", 95))

	// Display pod list
	for _, pod := range pods {
		age := time.Since(pod.CreatedAt).Truncate(time.Second)
		fmt.Printf("%-20s %-40s %-15s %-20s\n", pod.Namespace, pod.Name, pod.Status, age)
	}
}

// cleanupPodsWithStrategy cleans up pods with smart strategy
func cleanupPodsWithStrategy(pods []PodStatus) error {
	fmt.Println("\n开始清理...")
	var errors []string

	// 按状态和创建时间排序，优先清理已完成和失败且较旧的Pod
	sortPodsForCleanup(pods)

	for _, pod := range pods {
		if err := deletePodWithSmartCheck(pod); err != nil {
			errMsg := fmt.Sprintf("删除Pod %s/%s失败: %v", pod.Namespace, pod.Name, err)
			errors = append(errors, errMsg)
			fmt.Println(errMsg)
		}
	}

	if len(errors) > 0 {
		return fmt.Errorf("清理过程中发生%d个错误: %s", len(errors), strings.Join(errors, "; "))
	}

	fmt.Printf("\n[%s] 清理完成\n", time.Now().Format(time.RFC3339))
	return nil
}

// sortPodsForCleanup sorts pods for cleanup priority
func sortPodsForCleanup(pods []PodStatus) {
	// 定义状态优先级
	statusPriority := map[string]int{
		"Succeeded": 1, // 已完成的优先清理
		"Failed":    2, // 已失败的次优先
		"Unknown":   3, // 未知状态的再次之
		"Pending":   4, // Pending状态的最后清理
	}

	// 按状态优先级和创建时间排序
	for i := 0; i < len(pods); i++ {
		for j := i + 1; j < len(pods); j++ {
			// 比较状态优先级
			pri1 := statusPriority[pods[i].Status]
			pri2 := statusPriority[pods[j].Status]

			if pri1 > pri2 || (pri1 == pri2 && pods[i].CreatedAt.After(pods[j].CreatedAt)) {
				// 交换
				pods[i], pods[j] = pods[j], pods[i]
			}
		}
	}
}

// deletePodWithSmartCheck deletes a pod with smart checks
func deletePodWithSmartCheck(pod PodStatus) error {
	// 先检查当前状态
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	// 获取Pod的详细信息
	getCmd := exec.CommandContext(ctx, "kubectl", "get", "po", pod.Name, "-n", pod.Namespace, "-o", "json")
	output, err := getCmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("获取Pod信息失败: %v", err)
	}

	var podInfo map[string]interface{}
	if err := json.Unmarshal(output, &podInfo); err != nil {
		return fmt.Errorf("解析Pod信息失败: %v", err)
	}

	// 检查状态
	status, _ := podInfo["status"].(map[string]interface{})
	phase, _ := status["phase"].(string)

	// 如果现在是Running状态，需要智能判断
	if phase == "Running" {
		// 检查Pod的启动时间
		metadata, _ := podInfo["metadata"].(map[string]interface{})
		creationTimestamp, _ := metadata["creationTimestamp"].(string)
		createdAt, err := time.Parse(time.RFC3339, creationTimestamp)

		if err == nil {
			age := time.Since(createdAt)
			// 如果Pod是在检查之后才启动的（小于2分钟），跳过删除
			if age < 2*time.Minute {
				return fmt.Errorf("Pod刚启动(%v)，现在是Running状态，跳过删除", age)
			}
		}

		// 如果是长时间运行的Pod从非Running变为Running，这很异常，记录警告但不删除
		fmt.Printf("警告: Pod %s/%s 状态从 %s 变为 %s，可能是自愈行为，跳过删除\n",
			pod.Namespace, pod.Name, pod.Status, phase)
		return fmt.Errorf("Pod状态已变化为Running，跳过删除")
	}

	// 执行删除
	deleteCtx, deleteCancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer deleteCancel()

	deleteCmd := exec.CommandContext(deleteCtx, "kubectl", "delete", "po", pod.Name, "-n", pod.Namespace)
	deleteOutput, deleteErr := deleteCmd.CombinedOutput()
	if deleteErr != nil {
		return fmt.Errorf("%v, 输出: %s", deleteErr, string(deleteOutput))
	}

	fmt.Printf("成功删除Pod %s/%s\n", pod.Namespace, pod.Name)
	return nil
}

// StartPodCleanupLoop starts a loop that cleans up non-running pods at specified intervals
func StartPodCleanupLoop(interval time.Duration) {
	go func() {
		for {
			err := CleanupNonRunningPods()
			if err != nil {
				fmt.Printf("清理Pod过程中发生错误: %v\n", err)
			}

			fmt.Printf("等待%d小时后再次检查...\n", int(interval.Hours()))
			fmt.Println("=============================================================================================================================")
			time.Sleep(interval)
		}
	}()
}
